package com.sa.stp.parser;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.jaxen.JaxenException;
import org.jaxen.jdom.JDOMXPath;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import android.os.Environment;

import com.sa.stp.services.RealService;
import com.sa.stp.services.RealServiceImpl;
import com.sa.stp.services.VirtualService;
import com.sa.stp.services.VirtualServiceImpl;

public class ItemParserImpl implements ItemParser{

	private static final String PATH = "/sost-arch";
	private static final File SD_PATH = Environment
			.getExternalStorageDirectory();

	private Document xmlDocument;
	private Document oxmlDocument;
	private String alias;

	// Constructor del objeto, recive el File del XML
	public ItemParserImpl(File xml) {

		String aux=xml.getName();
		//TODO hacer expresion regular, se hacen cosas raras porque el split con el punto daba problemas
		String[] s=aux.split("&");
		String str=s[1].substring(0, s[1].length()-4);
		String[] elemento={s[0],str};
		this.alias = "";

		File xmlFile = xml;
		File oxmlFile = new File(SD_PATH + PATH + "/" + elemento[0] + "&" + elemento[1]
				+ ".oxml");

		try {

			// Creando Documents
			SAXBuilder builder = new SAXBuilder();

			xmlDocument = builder.build(new FileInputStream(xmlFile));

			oxmlDocument = builder.build(new FileInputStream(oxmlFile));

		} catch (Exception e) {
			throw new IllegalArgumentException(
					"Error while creating XMLParser: " + xmlFile.getName()
					+ " is not a valid XML File");
		}

	}

	public ItemParserImpl(String[] shortItem) {

		this(shortItem[0], shortItem[1], shortItem[2]);

	}

	public ItemParserImpl(String manufacturer, String model, String alias) {

		this.alias = alias;

		File xmlFile = new File(SD_PATH + PATH + "/" + manufacturer + "&" + model
				+ ".xml");
		File oxmlFile = new File(SD_PATH + PATH + "/" + manufacturer + "&" + model
				+ ".oxml");

		try {

			// Creando Documents
			SAXBuilder builder = new SAXBuilder();

			xmlDocument = builder.build(new FileInputStream(xmlFile));

			oxmlDocument = builder.build(new FileInputStream(oxmlFile));

		} catch (Exception e) {
			throw new IllegalArgumentException(
					"Error while creating XMLParser: " + xmlFile.getName()
					+ " is not a valid XML File");
		}
	}

	public Document getXmlDocument() {
		return xmlDocument;
	}

	public Document getOxmlDocument() {
		return oxmlDocument;
	}


	public static void generateOXML(String id, String manufacturer, String model) {

		Date d = new Date();
		String now = Long.toString(d.getTime());

		Element oxmlElement = new Element("oxml");
		Document myDocument = new Document(oxmlElement);

		Element statsElement = new Element("stats");
		oxmlElement.addContent(statsElement);

		Element device = new Element("device");
		statsElement.addContent(device);

		Element idElement = new Element("id");
		idElement.addContent(id);
		device.addContent(idElement);

		Element aliasElement = new Element("alias");
		aliasElement.addContent("");
		device.addContent(aliasElement);

		Element timesUsedElement = new Element("times-used");
		timesUsedElement.addContent("1");
		device.addContent(timesUsedElement);

		Element firstTimeElement = new Element("first-time");
		firstTimeElement.addContent(now);
		device.addContent(firstTimeElement);

		Element lastTimeElement = new Element("last-time");
		lastTimeElement.addContent(now);
		device.addContent(lastTimeElement);

		Element latitudeElement = new Element("latitude");
		latitudeElement.addContent("");
		device.addContent(latitudeElement);

		Element longitudeElement = new Element("longitude");
		longitudeElement.addContent("");
		device.addContent(longitudeElement);

		Element securityElement = new Element("security");
		securityElement.addContent("Not implemented yet");
		oxmlElement.addContent(securityElement);

		try {

			XMLOutputter outputter = new XMLOutputter(Format.getCompactFormat()
					.setIndent("     "));
			FileWriter writer = new FileWriter(SD_PATH + PATH + "/pruebas/"
					+ manufacturer + "&" + model + ".oxml");
			outputter.output(myDocument, writer);
			writer.close();

		} catch (java.io.IOException e) {
			e.printStackTrace();
		}
	}

	public List<String> getDevicesAlias() {
		// Acceso a /oxml/stats/device, extrae el alias de cada device y
		// devuelve una lista con todos los alias que aparecen en el
		// OXML

		List<String> aliases = new ArrayList<String>();

		Element root = oxmlDocument.getRootElement();
		Element stats = root.getChild("stats");
		List<Element> devicesOnOXML = stats.getChildren("device");

		for (Element device : devicesOnOXML) {
			String deviceAlias = device.getChild("alias").getValue();
			aliases.add(deviceAlias);
		}
		return aliases;
	}



	public String getValueFromXML(String attribute) {
		Element root = xmlDocument.getRootElement();
		Element info = root.getChild("device-info");
		return info.getChild(attribute).getValue();
	}

	public String getValue(String property) {

		JDOMXPath jx;
		String value="";

		try {
			jx = new JDOMXPath("/oxml/stats/device[alias=\"" + alias + "\"]");
			List<Element> result = (List<Element>) jx.evaluate(oxmlDocument);
			Element device =(Element) result.get(0);

			value = device.getChild(property).getValue();


		} catch (JaxenException e) {
			e.printStackTrace();
		}

		return value;

	}

	public List<RealService> getRealServices() {
		List<RealService> realServicesList = new ArrayList<RealService>();
		Element root = xmlDocument.getRootElement();
		Element services = root.getChild("services");
		List<Element> realServices = services.getChildren("real-service");

		for (Element realService : realServices) {

			String name = realService.getChild("name").getValue();
			String URL = realService.getChild("action-url").getValue();
			String description = realService.getChild("description").getValue();

			realServicesList.add(new RealServiceImpl(name, URL, description));

		}
		return realServicesList;
	}

	public List<VirtualService> getVirtualServices() {
		List<VirtualService> virtualServicesList = new ArrayList<VirtualService>();
		Element root = xmlDocument.getRootElement();
		Element services = root.getChild("services");
		List<Element> virtualServices = services.getChildren("virtual-service");
		
		for (Element virtualService : virtualServices) {

			String name = virtualService.getChild("name").getValue();
			String URL = virtualService.getChild("action-url").getValue();
			String description = virtualService.getChild("description").getValue();
			
			virtualServicesList.add(new VirtualServiceImpl(name, URL, description));
			
		}
		return virtualServicesList;
	}

}